001    package net.sf.xdc.processing;
002    
003    /*
004     *  Copyright 2005-2006 Jens Voß.
005     *
006     *  Licensed under the GNU Lesser General Public License (the "License");
007     *  you may not use this file except in compliance with the License.
008     *  You may obtain a copy of the License at
009     *
010     *       http://opensource.org/licenses/lgpl-license.php
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    import java.util.Map;
020    import java.util.HashMap;
021    import java.util.Set;
022    import java.util.HashSet;
023    import java.io.File;
024    
025    import net.sf.xdc.util.PathDescriptor;
026    
027    /**
028     * The <code>PatternSelector</code> class is an extension to the
029     * {@link FileSelector} class which allows to additionally restrict the set
030     * of selected files by specifying one or more {@link PathDescriptor}s
031     * (wildcard expressions).
032     *
033     * @author Jens Voß
034     * @since 0.5
035     * @version 0.5
036     */
037    public class PatternSelector extends FileSelector {
038    
039      private PathDescriptor[] descriptors;
040      private Map fileMap; // Map<File,Set<PathDescriptor>>
041    
042      /**
043       * Public constructor.
044       *
045       * @param dir This <code>PatternSelector</code>'s directory
046       * @param descriptors An array of wildcard expressions for this
047       *         <code>PatternSelector</code>
048       */
049      PatternSelector(File dir, PathDescriptor[] descriptors) {
050        super(dir, null, false);
051        this.descriptors = descriptors;
052      }
053    
054      /**
055       * This method retrieves the collection of all selected files within this
056       * <code>PatternSelector</code>'s directory which match the wildcard
057       * expression of one or more of its <code>PathDescriptor</code> objects.
058       *
059       * @return An array of files and directories in this
060       *          <code>PatternSelector</code>'s directory which match the wildcard
061       *          pattern of at least one of its path descriptors
062       */
063      protected File[] selectFiles() {
064        if (fileMap == null) {
065          fileMap = new HashMap();
066          for (int i = 0; i < descriptors.length; i++) {
067            PathDescriptor descriptor = descriptors[i];
068            File[] files = getDir().listFiles(descriptor);
069            for (int j = 0; j < files.length; j++) {
070              File file = files[j];
071              Set childDescriptors = (Set) fileMap.get(file);
072              if (childDescriptors == null) {
073                childDescriptors = new HashSet();
074                fileMap.put(file, childDescriptors);
075              }
076    //          if (descriptor.matches(file)) {
077                childDescriptors.add(descriptor.getChildDescriptor());
078    //          }
079              if (descriptor.matchesDirWithWildcard(file)) {
080                childDescriptors.add(descriptor);
081              }
082            }
083          }
084        }
085        Set files = fileMap.keySet();
086        return (File[]) files.toArray(new File[files.size()]);
087      }
088    
089      /**
090       * This method constructs a <code>PatternSelector</code> for a subdirectory of
091       * the current directory.
092       *
093       * @param subdirName The name of the subdirectory for which a new
094       *         <code>FileSelector</code> is to be constructed
095       * @return A new <code>PatternSelector</code> whose directory is the
096       *          subdirectory with the specified name
097       */
098      protected FileSelector moveToSubdir(String subdirName) {
099        File subdir = new File(getDir(), subdirName);
100        Set children = (Set) fileMap.get(subdir);
101        PathDescriptor[] childDescriptors = (PathDescriptor[]) children
102                .toArray(new PathDescriptor[children.size()]);
103        return new PatternSelector(subdir, childDescriptors);
104      }
105    }